// *********************************************************
//      Copyright (c) Kosta Gaitanis
//      All rights reserved
//
//      k.gaitanis@gmail.com
//
// *********************************************************

#include <math.h>
#include "Light.h"

Light::Light(const QString &name) :
    m_name(name),
    m_isOn(true)
{
    static int lightCount = 0;
    switch (lightCount) {
    case(0): m_lightId = GL_LIGHT0; break;
    case(1): m_lightId = GL_LIGHT1; break;
    case(2): m_lightId = GL_LIGHT2; break;
    case(3): m_lightId = GL_LIGHT3; break;
    case(4): m_lightId = GL_LIGHT4; break;
    case(5): m_lightId = GL_LIGHT5; break;
    case(6): m_lightId = GL_LIGHT6; break;
    case(7): m_lightId = GL_LIGHT7; break;
    default:
        qDebug() << "only 8 lights are allowed";
        m_lightId = -1;
    }

    if (m_name.isNull()) {
        m_name = QString("Light %1").arg(lightCount);
    }

    setAmbient(QColor(25, 25, 25));
    setDiffuse(Qt::white);
    setSpecular(Qt::white);
    setPosition(0.0, 0.0, 0.0);

    lightCount++;
}

Light::~Light()
{
}

void Light::initializeGL()
{
    // setup OpenGL lighting

    /* FIXME complete the code */
    // enable light
    glEnable(m_lightId);
    // set ambient, diffuse and specular components
    glLightfv(m_lightId, GL_AMBIENT, m_ambient); // set ambient components
    glLightfv(m_lightId, GL_DIFFUSE, m_diffuse); // set diffuse components
    glLightfv(m_lightId, GL_SPECULAR, m_specular); // set specular components
    /* STOP here */
}

void Light::paint()
{
    /* FIXME complete the code */
    // reset the light position since camera can move
    glLightfv(m_lightId, GL_POSITION, m_position);
    /* STOP here */
}

void Light::setAmbient(const QColor &ambient)
{
    m_ambient[0] = (GLfloat) ambient.redF();
    m_ambient[1] = (GLfloat) ambient.greenF();
    m_ambient[2] = (GLfloat) ambient.blueF();
    m_ambient[3] = (GLfloat) ambient.alphaF();

    /* FIXME complete the code */
    // setup gl light ambient parameter
    glLightfv(m_lightId, GL_AMBIENT, m_ambient);
    /* STOP here */
}

void Light::setDiffuse(const QColor &diffuse)
{
    m_diffuse[0] = (GLfloat) diffuse.redF();
    m_diffuse[1] = (GLfloat) diffuse.greenF();
    m_diffuse[2] = (GLfloat) diffuse.blueF();
    m_diffuse[3] = (GLfloat) diffuse.alphaF();

    /* FIXME complete the code */
    // setup gl light diffuse parameter
    glLightfv(m_lightId, GL_DIFFUSE, m_diffuse);
    /* STOP here */
}

void Light::setSpecular(const QColor &specular)
{
    m_specular[0] = (GLfloat) specular.redF();
    m_specular[1] = (GLfloat) specular.greenF();
    m_specular[2] = (GLfloat) specular.blueF();
    m_specular[3] = (GLfloat) specular.alphaF();

    /* FIXME complete the code */
    // setup gl light specular parameter
    glLightfv(m_lightId, GL_SPECULAR, m_specular);
    /* STOP here */
}

void Light::setPosition(double x, double y, double z, double w)
{
    m_position[0] = x;
    m_position[1] = y;
    m_position[2] = z;
    m_position[3] = w;
    /* FIXME complete the code */
    // setup gl light position parameter
    glLightfv(m_lightId, GL_POSITION, m_position);
    /* STOP here */
}

QColor Light::getAmbient() const
{
    return QColor(m_ambient[0]*255.0,
                  m_ambient[1]*255.0,
                  m_ambient[2]*255.0,
                  m_ambient[3]*255.0);
}

QColor Light::getDiffuse() const
{
    return QColor(m_diffuse[0]*255.0,
                  m_diffuse[1]*255.0,
                  m_diffuse[2]*255.0,
                  m_diffuse[3]*255.0);
}

QColor Light::getSpecular() const
{
    return QColor(m_specular[0]*255.0,
                  m_specular[1]*255.0,
                  m_specular[2]*255.0,
                  m_specular[3]*255.0);
}

const GLfloat *Light::getPosition() const
{
    return m_position;
}

const QString &Light::getName() const
{
    return m_name;
}

void Light::setOn(bool on)
{
    if (on) {
        glEnable(m_lightId);
    } else {
        glDisable(m_lightId);
    }
    m_isOn = on;
}

bool Light::isOn() const
{
    return m_isOn;
}

